package com.szh.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.szh.domain.OrderInfo;
import com.szh.service.AliPayService;
import com.szh.service.OrderInfoService;
import com.szh.vo.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;

/**
 *
 */
@Api(tags = "网站支付宝支付")
@CrossOrigin
@RestController
@RequestMapping("/api/aliPay")
public class AliPayController {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliPayController.class);

    @Autowired
    private AliPayService aliPayService;

    /**
     * 调用支付宝的统一收单下单并支付页面接口
     * @param productId 商品id
     * @return html形式的form表单，包含自动提交的脚本
     */
    @ApiOperation("统一收单下单并支付页面接口")
    @PostMapping("/trade/page/pay/{productId}")
    public R tradePagePay(@ApiParam(name = "productId", value = "商品id", required = true)
                          @PathVariable("productId") Long productId) {
        LOGGER.info("统一收单下单并支付页面接口的调用");
        //支付宝开放平台接受 request 请求对象后，会为开发者生成一个html形式的form表单，包含自动提交的脚本
        String formStr = aliPayService.tradeCreate(productId);
        //我们将form表单字符串返回给前端程序，之后前端将会调用自动提交脚本，进行表单的提交
        //此时，表单会自动提交到action属性所指向的支付宝开放平台中，从而为用户展示一个支付页面
        return R.ok().data("formStr", formStr);
    }

    /**
     * 支付完成之后的异步通知，支付宝会根据API中我们设置的 notify_url，通过 POST 请求的形式将支付结果作为参数通知给我们
     * @param params 通知参数
     * @return 支付结果
     */
    @ApiOperation(value = "支付通知")
    @PostMapping("/trade/notify")
    public String tradeNotify(@ApiParam(name = "params", value = "通知参数", required = true)
                              @RequestParam(value = "params") Map<String, String> params) {
        LOGGER.info("支付完成之后的异步通知");
        LOGGER.info("通知参数 ===> {}", JSON.toJSONString(params));
        return aliPayService.tradeNotify(params);
    }

    /**
     * 取消订单，调用支付宝统一收单交易关闭接口
     * @param orderNo 订单号
     * @return R
     */
    @ApiOperation("取消订单")
    @PostMapping("/trade/close/{orderNo}")
    public R cancel(@ApiParam(name = "orderNo", value = "订单号", required = true)
                    @PathVariable("orderNo") String orderNo) {
        LOGGER.info("取消订单");
        aliPayService.cancelOrder(orderNo);
        return R.ok().setMessage("订单已取消");
    }

    /**
     * 查询订单，调用支付宝统一收单交易查询接口
     * @param orderNo 订单号
     * @return R
     */
    @ApiOperation("查询订单")
    @PostMapping("/trade/query/{orderNo}")
    public R queryOrder(@ApiParam(name = "orderNo", value = "订单号", required = true)
                        @PathVariable("orderNo") String orderNo) {
        LOGGER.info("查询订单");
        String result = aliPayService.queryOrder(orderNo);
        return R.ok().setMessage("查询成功").data("result", result);
    }

    /**
     * 申请退单退款，调用支付宝统一收单交易退款接口
     * @param orderNo 订单号
     * @param reason 退款原因
     * @return R
     */
    @ApiOperation("申请退单退款")
    @PostMapping("/trade/refund/{orderNo}/{reason}")
    public R refund(@ApiParam(name = "orderNo", value = "订单号", required = true)
                    @PathVariable("orderNo") String orderNo,
                    @ApiParam(name = "reason", value = "退款原因", required = true)
                    @PathVariable("reason") String reason) {
        LOGGER.info("申请退单退款");
        aliPayService.refund(orderNo, reason);
        return R.ok();
    }

    /**
     * 查询退款，调用支付宝统一收单交易退款查询接口
     * @param orderNo 订单号
     * @return R
     */
    @ApiOperation("查询退款")
    @PostMapping("/trade/fastpay/refund/{orderNo}")
    public R queryRefund(@ApiParam(name = "orderNo", value = "订单号", required = true)
                         @PathVariable("orderNo") String orderNo) {
        LOGGER.info("查询退款");
        String result = aliPayService.queryRefund(orderNo);
        return R.ok().setMessage("查询成功").data("result", result);
    }

    /**
     * 根据账单类型和日期获取账单url地址，调用支付宝查询对账单下载地址接口
     * @param billDate 日期
     * @param type 账单类型
     * @return R
     */
    @ApiOperation("根据账单类型和日期获取账单url地址")
    @GetMapping("/bill/downloadurl/query/{billDate}/{type}")
    public R queryTradeBill(@ApiParam(name = "billDate", value = "日期", required = true)
                            @PathVariable("billDate") String billDate,
                            @ApiParam(name = "type", value = "账单类型", required = true)
                            @PathVariable("type") String type) {
        LOGGER.info("获取账单url");
        String downloadUrl = aliPayService.queryTradeBill(billDate, type);
        return R.ok().setMessage("获取账单url成功").data("downloadUrl", downloadUrl);
    }
}
